﻿using Microsoft.Exchange.WebServices.Data;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Task = System.Threading.Tasks.Task;

namespace EmailHelper.Exchange
{
    /// <summary>
    /// EWS文件夹帮助类
    /// </summary>
    public class EWSFoldersHelper
    {
        /// <summary>
        /// 隐藏现有文件夹
        /// </summary>
        /// <param name="folderId"></param>
        /// <param name="service"></param>
        /// <returns></returns>
        public async static Task MakeHidden(FolderId folderId, ExchangeService service)
        {
            // Create an extended property definition for the PidTagAttributeHidden property.
            ExtendedPropertyDefinition isHiddenProp = new ExtendedPropertyDefinition(0x10f4, MapiPropertyType.Boolean);
            PropertySet propSet = new PropertySet(isHiddenProp);
            // Bind to a folder and retrieve the PidTagAttributeHidden property.
            Folder folder = await Folder.Bind(service, folderId, propSet);
            folder.SetExtendedProperty(isHiddenProp, true);
            await folder.Update();
        }


        /// <summary>
        /// 查找MsgFolderRoot下所有隐藏的文件夹
        /// </summary>
        /// <param name="service"></param>
        public async static void FindHiddenFolders(ExchangeService service)
        {
            // Create an extended property definition for the PidTagAttributeHidden property.
            ExtendedPropertyDefinition isHiddenProp = new ExtendedPropertyDefinition(0x10f4, MapiPropertyType.Boolean);
            // Create a folder view to retrieve up to 100 folders and 
            // retrieve only the PidTagAttributeHidden and the display name.
            FolderView folderView = new FolderView(100);
            folderView.PropertySet = new PropertySet(isHiddenProp, FolderSchema.DisplayName);
            // Indicate a Traversal value of Deep, so that all subfolders are retrieved.
            folderView.Traversal = FolderTraversal.Deep;
            // Find all hidden folders under the MsgFolderRoot.
            // This call results in a FindFolder call to EWS.
            FindFoldersResults findFolder = await service.FindFolders(WellKnownFolderName.MsgFolderRoot,
                    new SearchFilter.IsEqualTo(isHiddenProp, true), folderView);  //改为false，则查看 非隐藏文件夹
            // Display the folder ID and display name of each hidden folder.
            foreach (Folder folder in findFolder)
            {
                Debug.WriteLine("FolderId: {0}", folder.Id);
                Debug.WriteLine("DisplayName: {0}", folder.DisplayName);
                Debug.WriteLine("\r\n");
            }
        }

        /// <summary>
        /// 创建文件夹
        /// </summary>
        /// <param name="service"></param>
        /// <returns></returns>
        public async static Task<bool> CreateFolder(ExchangeService service)
        {
            try
            {
                var cts = new CancellationTokenSource(30000);
                await Task.Run(() =>
                {
                    Folder folder = new Folder(service);
                    folder.DisplayName = "huy Custom Folders";
                    folder.FolderClass = "IPF.Note";
                    folder.Save(WellKnownFolderName.Inbox);
                }, cts.Token);
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }


        /// <summary>
        /// 获取指定的文件夹
        /// </summary>
        /// <param name="service"></param>
        /// <param name="wellKnown"></param>
        /// <returns></returns>
        public async static Task<Folder> GetFolder(ExchangeService service, WellKnownFolderName wellKnown)
        {
            try
            {
                var cts = new CancellationTokenSource(30000);
                var folder = await Task.Run(() =>
                {
                    PropertySet propSet = new PropertySet(BasePropertySet.FirstClassProperties);
                    return Folder.Bind(service, wellKnown, propSet);
                }, cts.Token);
                return folder;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 获取文件夹层次结构（默认获取MsgFolderRoot的结构）
        /// </summary>
        /// <param name="service"></param>
        /// <returns></returns>
        public async static Task<List<Folder>> FindFolders(ExchangeService service)
        {
            try
            {
                var cts = new CancellationTokenSource(30000);
                var folders = await Task.Run(() =>
                {
                    // Create a new folder view, and pass in the maximum number of folders to return.
                    int maxFolderViewSize = 100;
                    FolderView view = new FolderView(maxFolderViewSize);
                    // Create an extended property definition for the PR_ATTR_HIDDEN property,
                    // so that your results will indicate whether the folder is a hidden folder.
                    ExtendedPropertyDefinition isHiddenProp = new ExtendedPropertyDefinition(0x10f4, MapiPropertyType.Boolean);
                    // 定义需要返回哪些属性
                    //view.PropertySet = new PropertySet(BasePropertySet.IdOnly, FolderSchema.DisplayName, isHiddenProp);

                    view.PropertySet = new PropertySet(BasePropertySet.FirstClassProperties,isHiddenProp);

                    // Indicate a Traversal value of Deep, so that all subfolders are retrieved.
                    view.Traversal = FolderTraversal.Deep;
                    // Call FindFolders to retrieve the folder hierarchy, starting with the MsgFolderRoot folder.
                    return service.FindFolders(WellKnownFolderName.MsgFolderRoot, view);
                }, cts.Token);
                if (folders != null)
                {
                    //return folders.Folders.ToList();
                    //过滤一些不要的文件夹
                    List<Folder> res = new List<Folder>();
                    foreach (var item in folders.Folders)
                    {
                        //过滤一些文件夹
                        if (item.FolderClass != null && !item.FolderClass.ToLowerInvariant().Contains("ipf.note"))
                            continue;
                        res.Add(item);
                    }
                    return res;
                }
                return null;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        /// <summary>
        /// 获取文件夹层次结构（根据特定文件夹id）
        /// </summary>
        /// <param name="service"></param>
        /// <param name="folderId"></param>
        /// <returns></returns>
        public async static Task<List<Folder>> FindFoldersByFoldId(ExchangeService service, FolderId folderId)
        {
            try
            {
                var cts = new CancellationTokenSource(30000);
                var folders = await Task.Run(() =>
                {
                    // Create a new folder view, and pass in the maximum number of folders to return.
                    int maxFolderViewSize = 100;
                    FolderView view = new FolderView(maxFolderViewSize);
                    // Create an extended property definition for the PR_ATTR_HIDDEN property,
                    // so that your results will indicate whether the folder is a hidden folder.
                    //ExtendedPropertyDefinition isHiddenProp = new ExtendedPropertyDefinition(0x10f4, MapiPropertyType.Boolean);
                    //// 定义需要返回哪些属性
                    //view.PropertySet = new PropertySet(BasePropertySet.IdOnly, FolderSchema.DisplayName, isHiddenProp);

                    view.PropertySet = new PropertySet(BasePropertySet.FirstClassProperties);

                    // Indicate a Traversal value of Deep, so that all subfolders are retrieved.
                    view.Traversal = FolderTraversal.Deep;
                    // Call FindFolders to retrieve the folder hierarchy, starting with the MsgFolderRoot folder.
                    return service.FindFolders(folderId, view);
                }, cts.Token);
                if (folders != null)
                {
                    //return folders.Folders.ToList();
                    //过滤一些不要的文件夹
                    List<Folder> res = new List<Folder>();
                    foreach (var item in folders.Folders)
                    {
                        //过滤一些文件夹
                        if (item.FolderClass != null && !item.FolderClass.ToLowerInvariant().Contains("ipf.note"))
                            continue;
                        res.Add(item);
                    }
                    return res;
                }
                return null;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }


        /// <summary>
        /// 更新文件夹
        /// </summary>
        /// <param name="service"></param>
        /// <returns></returns>
        public async static Task<bool> UpdateFolder(ExchangeService service)
        {
            try
            {
                var cts = new CancellationTokenSource(30000);
                var rootfolder = await Task.Run(() =>
                {
                    PropertySet propSet = new PropertySet(BasePropertySet.FirstClassProperties);
                    //邮件文件夹层次结构的根
                    return Folder.Bind(service, WellKnownFolderName.MsgFolderRoot, propSet);
                    //await Item.Bind(service, new ItemId(rootfolder.Id.UniqueId), new PropertySet(BasePropertySet.FirstClassProperties));
                    //rootfolder.ChildFolderCount

                    //var result = service.FindFolders.GetFolderLogin(config, DistinguishedFolderIdNameType.msgfolderroot);
                }, cts.Token);
                if (rootfolder != null && rootfolder.ChildFolderCount > 0)
                {
                    return true;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return false;
        }

        /// <summary>
        /// 删除文件夹
        /// </summary>
        /// <param name="service"></param>
        /// <returns></returns>
        public async static Task<bool> DeleteFolder(ExchangeService service)
        {
            try
            {
                var cts = new CancellationTokenSource(30000);
                var rootfolder = await Task.Run(() =>
                {
                    PropertySet propSet = new PropertySet(BasePropertySet.FirstClassProperties);
                    //邮件文件夹层次结构的根
                    return Folder.Bind(service, WellKnownFolderName.MsgFolderRoot, propSet);
                    //await Item.Bind(service, new ItemId(rootfolder.Id.UniqueId), new PropertySet(BasePropertySet.FirstClassProperties));
                    //rootfolder.ChildFolderCount

                    //var result = service.FindFolders.GetFolderLogin(config, DistinguishedFolderIdNameType.msgfolderroot);
                }, cts.Token);
                if (rootfolder != null && rootfolder.ChildFolderCount > 0)
                {
                    return true;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return false;
        }


    }
}
